package guda.house.biz.impl;

import guda.grape.autogen.common.page.BizResult;
import guda.grape.util.Convert;
import guda.house.biz.FrontFeeBiz;
import guda.house.biz.beans.vo.BillPayVO;
import guda.house.biz.beans.vo.PayDetail;
import guda.house.biz.beans.vo.PayDetailVO;
import guda.house.biz.beans.vo.SuiteView;
import guda.house.biz.constants.CommonResultCode;
import guda.house.biz.enums.WxPayStatusEnum;
import guda.house.biz.query.*;
import guda.house.biz.security.AuthUser;
import guda.house.biz.util.PriceUtil;
import guda.house.biz.util.Transform;
import guda.house.biz.util.TransformHelper;
import guda.house.dal.dao.*;
import guda.house.dal.dataobject.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Created by well on 16/5/27.
 */
public class FrontFeeBizImpl implements FrontFeeBiz {

    @Autowired
    private WxSuiteRelDAO wxSuiteRelDAO;
    @Autowired
    private WxAccessDAO wxAccessDAO;
    @Autowired
    private WxPayOrderDAO wxPayOrderDAO;
    @Autowired
    private WxPayDetailDAO wxPayDetailDAO;
    @Autowired
    private BillEstateDAO billEstateDAO;
    @Autowired
    private BillElecDAO billElecDAO;
    @Autowired
    private BillWaterDAO billWaterDAO;
    @Autowired
    private BillParkingDAO billParkingDAO;
    @Autowired
    private SuiteDAO suiteDAO;
    @Autowired
    private UnitDAO unitDAO;
    @Autowired
    private BuildingDAO buildingDAO;
    @Autowired
    private VillageDAO villageDAO;
    @Autowired
    private OwnerDAO ownerDAO;
    @Autowired
    private BillPayDAO billPayDAO;
    @Autowired
    private BillExtDAO billExtDAO;
    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public BizResult queryUnpayFee(FrontFeeQuery frontFeeQuery) {
        BizResult bizResult = new BizResult();
        Long accessId = AuthUser.getCurrentUser().getUserId();
        final WxAccessDO wxAccessById = wxAccessDAO.getWxAccessById(accessId);
        if(wxAccessById == null){
            bizResult.code= CommonResultCode.PERM_ERROR;
            return  bizResult;
        }
        Date start = null;
        Date end = null;
        if (StringUtils.hasText(frontFeeQuery.getStartDate()) && StringUtils.hasText(frontFeeQuery.getEndDate())) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                start = simpleDateFormat.parse(frontFeeQuery.getStartDate());
            } catch (ParseException e) {
            }
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                end = simpleDateFormat.parse(frontFeeQuery.getEndDate());
            } catch (ParseException e) {
            }
        }
        WxSuiteRelQuery wxSuiteRelQuery = new WxSuiteRelQuery();
        wxSuiteRelQuery.setPageSize(1000);
        wxSuiteRelQuery.setUnionid(wxAccessById.getUnionid());
        wxSuiteRelQuery.setOpenid(wxAccessById.getOpenid());
        List<WxSuiteRelDO> wxSuiteRelDOs = wxSuiteRelDAO.selectForPage(wxSuiteRelQuery);
        if (wxSuiteRelDOs.size() == 0) {
            bizResult.success = true;
            return bizResult;
        }
        List<PayDetailVO> payDetailVOList = new ArrayList<PayDetailVO>();
        for (WxSuiteRelDO wxSuiteRelDO : wxSuiteRelDOs) {
            List<BillElecDO> billElecDOList = new ArrayList<BillElecDO>();
            List<BillWaterDO> billWaterDOList = new ArrayList<BillWaterDO>();
            List<BillEstateDO> billEstateDOList = new ArrayList<BillEstateDO>();
            List<BillParkingDO> billParkingDOList = new ArrayList<BillParkingDO>();
            if ("water".equals(frontFeeQuery.getFeeType())) {
                BillWaterQuery billWaterQuery = new BillWaterQuery();
                billWaterQuery.setPageSize(500);
                billWaterQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billWaterQuery.setEndDate(end);
                billWaterQuery.setStartDate(start);
                billWaterDOList = billWaterDAO.selectForUnpay(billWaterQuery);

            } else if ("elec".equals(frontFeeQuery.getFeeType())) {
                BillElecQuery billElecQuery = new BillElecQuery();
                billElecQuery.setPageSize(500);
                billElecQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billElecQuery.setEndDate(end);
                billElecQuery.setStartDate(start);
                billElecDOList = billElecDAO.selectForUnpay(billElecQuery);

            } else if ("estate".equals(frontFeeQuery.getFeeType())) {
                BillEstateQuery billEstateQuery = new BillEstateQuery();
                billEstateQuery.setPageSize(500);
                billEstateQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billEstateQuery.setEndDate(end);
                billEstateQuery.setStartDate(start);
                billEstateDOList = billEstateDAO.selectForUnpay(billEstateQuery);

            } else if ("parking".equals(frontFeeQuery.getFeeType())) {
                BillParkingQuery billParkingQuery = new BillParkingQuery();
                billParkingQuery.setPageSize(500);
                billParkingQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billParkingQuery.setEndDate(end);
                billParkingQuery.setStartDate(start);
                billParkingDOList = billParkingDAO.selectForUnpay(billParkingQuery);
            } else {

                BillParkingQuery billParkingQuery = new BillParkingQuery();
                billParkingQuery.setPageSize(500);
                billParkingQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billParkingQuery.setEndDate(end);
                billParkingQuery.setStartDate(start);
                billParkingDOList = billParkingDAO.selectForUnpay(billParkingQuery);

                BillEstateQuery billEstateQuery = new BillEstateQuery();
                billEstateQuery.setPageSize(500);
                billEstateQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billEstateQuery.setEndDate(end);
                billEstateQuery.setStartDate(start);
                billEstateDOList = billEstateDAO.selectForUnpay(billEstateQuery);

                BillWaterQuery billWaterQuery = new BillWaterQuery();
                billWaterQuery.setPageSize(500);
                billWaterQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billWaterQuery.setEndDate(end);
                billWaterQuery.setStartDate(start);
                billWaterDOList = billWaterDAO.selectForUnpay(billWaterQuery);

                BillElecQuery billElecQuery = new BillElecQuery();
                billElecQuery.setPageSize(500);
                billElecQuery.setSuiteId(wxSuiteRelDO.getSuiteId());
                billElecQuery.setEndDate(end);
                billElecQuery.setStartDate(start);
                billElecDOList = billElecDAO.selectForUnpay(billElecQuery);

            }

            long allTotal = 0L;
            PayDetailVO payDetailVO = new PayDetailVO();
            List<PayDetail> payDetailList = new ArrayList<PayDetail>();
            payDetailVO.setPayDetailList(payDetailList);
            if (billEstateDOList.size() > 0) {
                Collections.sort(billEstateDOList, new Comparator<BillEstateDO>() {
                    @Override
                    public int compare(BillEstateDO o1, BillEstateDO o2) {
                        return o2.getGmtStart().compareTo(o1.getGmtStart());
                    }
                });
                BillEstateDO billEstateDO = billEstateDOList.get(0);
                if (payDetailVO.getVillageDO() == null) {
                    SuiteDO suiteById = suiteDAO.getSuiteById(billEstateDO.getSuiteId());
                    payDetailVO.setSuiteDO(suiteById);
                    UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                    payDetailVO.setUnitDO(unitById);
                    BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
                    payDetailVO.setBuildingDO(buildingById);
                    payDetailVO.setVillageDO(villageDAO.getVillageById(buildingById.getVillageId()));
                    OwnerQuery ownerQuery = new OwnerQuery();
                    ownerQuery.setSuiteId(suiteById.getSuiteId());
                    List<OwnerDO> ownerDOs = ownerDAO.selectForPage(ownerQuery);
                    payDetailVO.setOwnerDOList(ownerDOs);
                    payDetailVO.setGmt(billEstateDO.getGmtCreate());
                }
                PayDetail payDetail = new PayDetail();
                payDetail.setFeeName("物业费");
                payDetail.setStart(billEstateDOList.get(billEstateDOList.size() - 1).getGmtStart());
                payDetail.setEnd(billEstateDOList.get(0).getGmtEnd());

                List<String> billId = TransformHelper.transform(billEstateDOList, new Transform<BillEstateDO, String>() {
                    @Override
                    public String transform(BillEstateDO object) {
                        return "estate_" + object.getBillId();
                    }
                });
                payDetail.setBillIdList(billId);

                long c = 0L;
                for (BillEstateDO billEstateDO1 : billEstateDOList) {
                    c = c + billEstateDO1.getPayTotal();
                }
                payDetail.setPayTotal(c);
                payDetailList.add(payDetail);
                allTotal = allTotal + payDetail.getPayTotal();
            }

            if (billWaterDOList.size() > 0) {
                Collections.sort(billWaterDOList, new Comparator<BillWaterDO>() {
                    @Override
                    public int compare(BillWaterDO o1, BillWaterDO o2) {
                        return o2.getGmtStart().compareTo(o1.getGmtStart());
                    }
                });
                BillWaterDO billWaterDO = billWaterDOList.get(0);
                if (payDetailVO.getVillageDO() == null) {
                    SuiteDO suiteById = suiteDAO.getSuiteById(billWaterDO.getSuiteId());
                    payDetailVO.setSuiteDO(suiteById);
                    UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                    payDetailVO.setUnitDO(unitById);
                    BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
                    payDetailVO.setBuildingDO(buildingById);
                    payDetailVO.setVillageDO(villageDAO.getVillageById(buildingById.getVillageId()));
                    OwnerQuery ownerQuery = new OwnerQuery();
                    ownerQuery.setSuiteId(suiteById.getSuiteId());
                    List<OwnerDO> ownerDOs = ownerDAO.selectForPage(ownerQuery);
                    payDetailVO.setOwnerDOList(ownerDOs);
                    payDetailVO.setGmt(billWaterDO.getGmtCreate());
                }
                PayDetail payDetail = new PayDetail();
                payDetail.setFeeName("水费");
                payDetail.setStart(billWaterDOList.get(billWaterDOList.size() - 1).getGmtStart());
                payDetail.setEnd(billWaterDOList.get(0).getGmtEnd());


                List<String> billId = TransformHelper.transform(billWaterDOList, new Transform<BillWaterDO, String>() {
                    @Override
                    public String transform(BillWaterDO object) {
                        return "water_" + object.getBillId();
                    }
                });
                payDetail.setBillIdList(billId);

                long c = 0L;
                for (BillWaterDO billWaterDO1 : billWaterDOList) {
                    c = c + billWaterDO1.getPayTotal();
                }
                payDetail.setPayTotal(c);
                payDetailList.add(payDetail);
                allTotal = allTotal + payDetail.getPayTotal();
            }

            if (billElecDOList.size() > 0) {
                Collections.sort(billElecDOList, new Comparator<BillElecDO>() {
                    @Override
                    public int compare(BillElecDO o1, BillElecDO o2) {
                        return o2.getGmtStart().compareTo(o1.getGmtStart());
                    }
                });
                BillElecDO billElecDO = billElecDOList.get(0);
                if (payDetailVO.getVillageDO() == null) {
                    SuiteDO suiteById = suiteDAO.getSuiteById(billElecDO.getSuiteId());
                    payDetailVO.setSuiteDO(suiteById);
                    UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                    payDetailVO.setUnitDO(unitById);
                    BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
                    payDetailVO.setBuildingDO(buildingById);
                    payDetailVO.setVillageDO(villageDAO.getVillageById(buildingById.getVillageId()));
                    OwnerQuery ownerQuery = new OwnerQuery();
                    ownerQuery.setSuiteId(suiteById.getSuiteId());
                    List<OwnerDO> ownerDOs = ownerDAO.selectForPage(ownerQuery);
                    payDetailVO.setOwnerDOList(ownerDOs);
                    payDetailVO.setGmt(billElecDO.getGmtCreate());
                }
                PayDetail payDetail = new PayDetail();
                payDetail.setFeeName("电费");

                payDetail.setStart(billElecDOList.get(billElecDOList.size() - 1).getGmtStart());
                payDetail.setEnd(billElecDOList.get(0).getGmtEnd());


                List<String> billId = TransformHelper.transform(billElecDOList, new Transform<BillElecDO, String>() {
                    @Override
                    public String transform(BillElecDO object) {
                        return "elec_" + object.getBillId();
                    }
                });
                payDetail.setBillIdList(billId);

                long c = 0L;
                for (BillElecDO billElecDO1 : billElecDOList) {
                    c = c + billElecDO1.getPayTotal();
                }
                payDetail.setPayTotal(c);
                payDetailList.add(payDetail);
                allTotal = allTotal + payDetail.getPayTotal();
            }
            if (billParkingDOList.size() > 0) {
                Collections.sort(billParkingDOList, new Comparator<BillParkingDO>() {
                    @Override
                    public int compare(BillParkingDO o1, BillParkingDO o2) {
                        return o2.getGmtStart().compareTo(o1.getGmtStart());
                    }
                });
                BillParkingDO billParkingDO = billParkingDOList.get(0);
                if (payDetailVO.getVillageDO() == null) {
                    SuiteDO suiteById = suiteDAO.getSuiteById(billParkingDO.getSuiteId());
                    payDetailVO.setSuiteDO(suiteById);
                    UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
                    payDetailVO.setUnitDO(unitById);
                    BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
                    payDetailVO.setBuildingDO(buildingById);
                    payDetailVO.setVillageDO(villageDAO.getVillageById(buildingById.getVillageId()));
                    OwnerQuery ownerQuery = new OwnerQuery();
                    ownerQuery.setSuiteId(suiteById.getSuiteId());
                    List<OwnerDO> ownerDOs = ownerDAO.selectForPage(ownerQuery);
                    payDetailVO.setOwnerDOList(ownerDOs);
                    payDetailVO.setGmt(billParkingDO.getGmtCreate());
                }

                PayDetail payDetail = new PayDetail();
                payDetail.setFeeName("车位费");
                payDetail.setStart(billParkingDOList.get(billParkingDOList.size() - 1).getGmtStart());
                payDetail.setEnd(billParkingDOList.get(0).getGmtEnd());

                List<String> billId = TransformHelper.transform(billParkingDOList, new Transform<BillParkingDO, String>() {
                    @Override
                    public String transform(BillParkingDO object) {
                        return "parking_" + object.getBillId();
                    }
                });
                payDetail.setBillIdList(billId);

                long c = 0L;
                for (BillParkingDO billParkingDO1 : billParkingDOList) {
                    c = c + billParkingDO1.getPayTotal();
                }
                payDetail.setPayTotal(c);
                payDetailList.add(payDetail);
                allTotal = allTotal + payDetail.getPayTotal();

            }
            if(payDetailList.size() ==0){
                continue;
            }
            payDetailVO.setPayTotal(allTotal);
            payDetailVO.setPayTotalCN(PriceUtil.toRMB(allTotal));
            payDetailVOList.add(payDetailVO);
        }


        bizResult.data.put("payDetailVOList", payDetailVOList);
        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult queryPaiedFee(FrontFeeQuery frontFeeQuery) {
        BizResult bizResult = new BizResult();
        Long accessId = AuthUser.getCurrentUser().getUserId();
        final WxAccessDO wxAccessById = wxAccessDAO.getWxAccessById(accessId);
        if(wxAccessById == null){
            bizResult.code= CommonResultCode.PERM_ERROR;
            return  bizResult;
        }
        WxSuiteRelQuery wxSuiteRelQuery = new WxSuiteRelQuery();
        wxSuiteRelQuery.setPageSize(1000);
        wxSuiteRelQuery.setUnionid(wxAccessById.getUnionid());
        wxSuiteRelQuery.setOpenid(wxAccessById.getOpenid());
        List<WxSuiteRelDO> wxSuiteRelDOs = wxSuiteRelDAO.selectForPage(wxSuiteRelQuery);
        if (wxSuiteRelDOs.size() == 0) {
            bizResult.success = true;
            return bizResult;
        }
        List<Long> suiteIdList = TransformHelper.transform(wxSuiteRelDOs, new Transform<WxSuiteRelDO, Long>() {
            @Override
            public Long transform(WxSuiteRelDO object) {
                return object.getSuiteId();
            }
        });
        Date start = null;
        Date end = null;
        if (StringUtils.hasText(frontFeeQuery.getStartDate()) && StringUtils.hasText(frontFeeQuery.getEndDate())) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                start = simpleDateFormat.parse(frontFeeQuery.getStartDate());
            } catch (ParseException e) {
            }
            simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                end = simpleDateFormat.parse(frontFeeQuery.getEndDate());
            } catch (ParseException e) {
            }
        }

        BillPayQuery billPayQuery = new BillPayQuery();
        if (suiteIdList.size() == 1) {
            billPayQuery.setSuiteId(suiteIdList.get(0));
        } else {
            billPayQuery.setSuiteIdList(suiteIdList);
        }
        billPayQuery.setStartDate(start);
        billPayQuery.setEndDate(end);
        billPayQuery.setPageNo(frontFeeQuery.getPageNo());
        billPayQuery.setPageSize(frontFeeQuery.getPageSize());
        List<BillPayDO> billPayList = billPayDAO.selectForPayedLog(billPayQuery);
        List<BillPayVO> billPayVOList = new ArrayList<BillPayVO>();
        for(BillPayDO billPayDO:billPayList){
            BillPayVO billPayVO = new BillPayVO();
            billPayVO.setBillPayDO(billPayDO);

            SuiteDO suiteById = suiteDAO.getSuiteById(billPayDO.getSuiteId());
            billPayVO.setSuiteDO(suiteById);
            if (suiteById == null) {
                continue;
            }
            UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
            if (unitById == null) {
                continue;
            }
            billPayVO.setUnitDO(unitById);
            BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
            if (buildingById == null) {
                continue;
            }
            billPayVO.setBuildingDO(buildingById);
            VillageDO villageDO = villageDAO.getVillageById(buildingById.getVillageId());
            if (villageDO == null) {
                continue;
            }
            billPayVO.setVillageDO(villageDO);
            billPayVOList.add(billPayVO);

        }
        int totalCount = billPayDAO.countForPayedLog(billPayQuery);
        billPayQuery.setTotalCount(totalCount);

        bizResult.data.put("query", billPayQuery);

        bizResult.data.put("billPayVOList", billPayVOList);

        bizResult.success = true;
        return bizResult;
    }

    @Override
    public BizResult createOrder( String billPayId) {
        BizResult bizResult = new BizResult();

        Long accessId = AuthUser.getCurrentUser().getUserId();
        final WxAccessDO wxAccessById = wxAccessDAO.getWxAccessById(accessId);
        if(wxAccessById == null){
            bizResult.code= CommonResultCode.PERM_ERROR;
            return  bizResult;
        }
        WxSuiteRelQuery wxSuiteRelQuery = new WxSuiteRelQuery();
        wxSuiteRelQuery.setPageSize(1000);
        wxSuiteRelQuery.setUnionid(wxAccessById.getUnionid());
        wxSuiteRelQuery.setOpenid(wxAccessById.getOpenid());
        List<WxSuiteRelDO> wxSuiteRelDOs = wxSuiteRelDAO.selectForPage(wxSuiteRelQuery);
        Set<Long> suiteIdSet = TransformHelper.transform2Set(wxSuiteRelDOs, new Transform<WxSuiteRelDO, Long>() {
            @Override
            public Long transform(WxSuiteRelDO object) {
                return object.getSuiteId();
            }
        });
        long total = 0;
        final String[] billIdList = billPayId.split(",");
        final StringBuilder buf = new StringBuilder();
        Long suiteId = null;
        for (String billId : billIdList) {
            String[] split = billId.split("_");
            if ("parking".equals(split[0])) {
                BillParkingDO billParkingById = billParkingDAO.getBillParkingById(Convert.toLong(split[1]));
                if (!suiteIdSet.contains(billParkingById.getSuiteId().longValue())) {
                    throw new RuntimeException("非法支付");
                }
                if (billParkingById.getIsPayed() != null && billParkingById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                suiteId = billParkingById.getSuiteId();
                total = total + billParkingById.getPayTotal();
                buf.append("车位费（").append(billParkingById.getRecordYear())
                        .append("年").append(billParkingById.getRecordMonth()).append("月）：").append(PriceUtil.formatCNY(billParkingById.getPayTotal())).append("元;");
            } else if ("estate".equals(split[0])) {
                BillEstateDO billEstateById = billEstateDAO.getBillEstateById(Convert.toLong(split[1]));
                if (!suiteIdSet.contains(billEstateById.getSuiteId().longValue())) {
                    throw new RuntimeException("非法支付");
                }
                if (billEstateById.getIsPayed() != null && billEstateById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                suiteId = billEstateById.getSuiteId();
                total = total + billEstateById.getPayTotal();
                buf.append("物业费（").append(billEstateById.getRecordYear())
                        .append("年").append(billEstateById.getRecordMonth()).append("月）：").append(PriceUtil.formatCNY(billEstateById.getPayTotal())).append("元;");
            } else if ("water".equals(split[0])) {
                BillWaterDO billWaterById = billWaterDAO.getBillWaterById(Convert.toLong(split[1]));
                if (!suiteIdSet.contains(billWaterById.getSuiteId().longValue())) {
                    throw new RuntimeException("非法支付");
                }
                if (billWaterById.getIsPayed() != null && billWaterById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                total = total + billWaterById.getPayTotal();
                suiteId = billWaterById.getSuiteId();
                buf.append("水费（").append(billWaterById.getRecordYear())
                        .append("年").append(billWaterById.getRecordMonth()).append("月）：").append(PriceUtil.formatCNY(billWaterById.getPayTotal())).append("元;");
            } else if ("elec".equals(split[0])) {
                BillElecDO billElecById = billElecDAO.getBillElecById(Convert.toLong(split[1]));
                if (!suiteIdSet.contains(billElecById.getSuiteId().longValue())) {
                    throw new RuntimeException("非法支付");
                }
                if (billElecById.getIsPayed() != null && billElecById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                suiteId = billElecById.getSuiteId();
                total = total + billElecById.getPayTotal();
                buf.append("电费（").append(billElecById.getRecordYear())
                        .append("年").append(billElecById.getRecordMonth()).append("月）：").append(PriceUtil.formatCNY(billElecById.getPayTotal())).append("元;");
            } else if ("deposit".equals(split[0])) {
                BillExtDO billExtById = billExtDAO.getBillExtById(Convert.toLong(split[1]));
                if (billExtById.getIsPayed() != null && billExtById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                suiteId = billExtById.getSuiteId();
                total = total + billExtById.getPayTotal();
                buf.append("押金:").append(PriceUtil.formatCNY(billExtById.getPayTotal())).append("元;");
            } else if ("other".equals(split[0])) {
                BillExtDO billExtById = billExtDAO.getBillExtById(Convert.toLong(split[1]));
                if (billExtById.getIsPayed() != null && billExtById.getIsPayed().intValue() == 1) {
                    throw new RuntimeException("订单已付款");
                }
                suiteId = billExtById.getSuiteId();
                total = total + billExtById.getPayTotal();
                buf.append("其他费用:").append(PriceUtil.formatCNY(billExtById.getPayTotal())).append("元;");
            }

        }
        final long payTotal = total;
        final long paySuiteId = suiteId;
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                WxPayOrderDO wxPayOrderDO = new WxPayOrderDO();
                wxPayOrderDO.setUnionid(wxAccessById.getUnionid());
                wxPayOrderDO.setOpenid(wxAccessById.getOpenid());
                wxPayOrderDO.setOrderContent(buf.toString());
                wxPayOrderDO.setPayStatus(WxPayStatusEnum.init.getVal());
                wxPayOrderDO.setPayTotal(payTotal);
                wxPayOrderDO.setSuiteId(paySuiteId);
                wxPayOrderDO.setOrderNo(OrderNoHelper.next(1));
                Long insert = wxPayOrderDAO.insert(wxPayOrderDO);

                for (String billId : billIdList) {
                    String[] split = billId.split("_");
                    WxPayDetailDO wxPayDetailDO = new WxPayDetailDO();
                    wxPayDetailDO.setOrderId(insert);
                    wxPayDetailDO.setBillId(Convert.toLong(split[1]));
                    wxPayDetailDO.setBillType(split[0]);
                    wxPayDetailDAO.insert(wxPayDetailDO);
                }
            }
        });
        bizResult.success = true;
        return bizResult;
    }

    public static class OrderNoHelper {
        static AtomicInteger atomicInteger = new AtomicInteger(0);

        private static String random() {
            int i = atomicInteger.addAndGet(1);
            if (i > 100) {
                atomicInteger.set(0);
            }
            return appendZero(String.valueOf(i), 3);
        }

        public static String next(long itemId) {
            SimpleDateFormat simpleFormatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            String s = simpleFormatter.format(new Date());
            return s + appendZero(String.valueOf(itemId), 8) + random();
        }

        private static String appendZero(String str, int strLength) {
            int strLen = str.length();
            StringBuilder buf = new StringBuilder();
            if (strLen < strLength) {
                for (int i = 0, len = strLength - strLen; i < len; ++i) {
                    buf.append("0");
                }
            }
            buf.append(str);
            return buf.toString();
        }

    }

    @Override
    public BizResult paySuccess(final Long orderId, final String wxTradeNo) {
        BizResult bizResult = new BizResult();
        final WxPayOrderDO wxPayOrderById = wxPayOrderDAO.getWxPayOrderById(orderId);

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                WxPayOrderDO wxPayOrderDOTemp = new WxPayOrderDO();
                wxPayOrderDOTemp.setOrderId(orderId);
                wxPayOrderDOTemp.setOutTradeNo(wxTradeNo);
                wxPayOrderDOTemp.setPayStatus(WxPayStatusEnum.pay.getVal());
                wxPayOrderDOTemp.setGmtPay(new Date());
                wxPayOrderDAO.updateByIdSelective(wxPayOrderDOTemp);

                BillPayDO billPayDO = new BillPayDO();
                billPayDO.setSuiteId(wxPayOrderById.getSuiteId());
                billPayDO.setPayTypeId(0L);
                billPayDO.setPayTotal(wxPayOrderById.getPayTotal());
                billPayDO.setPayDesc(wxPayOrderById.getOrderContent());
                billPayDO.setPayTotalCharge(0L);

                billPayDO.setPayType("网上支付");
                Long payId = billPayDAO.insert(billPayDO);
                List<WxPayDetailDO> wxPayDetailByOrderId = wxPayDetailDAO.getWxPayDetailByOrderId(orderId);
                for (WxPayDetailDO wxPayDetailDO : wxPayDetailByOrderId) {
                    if ("parking".equals(wxPayDetailDO.getBillType())) {
                        BillParkingDO billParkingById = billParkingDAO.getBillParkingById(wxPayDetailDO.getBillId());
                        billParkingById.setIsPayed(1);
                        billParkingById.setGmtPay(new Date());
                        billParkingById.setBillPayId(payId);
                        billParkingDAO.updateByIdSelective(billParkingById);
                    } else if ("estate".equals(wxPayDetailDO.getBillType())) {
                        BillEstateDO billEstateById = billEstateDAO.getBillEstateById(wxPayDetailDO.getBillId());
                        billEstateById.setIsPayed(1);
                        billEstateById.setGmtPay(new Date());
                        billEstateById.setBillPayId(payId);
                        billEstateDAO.updateByIdSelective(billEstateById);
                    } else if ("water".equals(wxPayDetailDO.getBillType())) {

                        BillWaterDO billWaterById = billWaterDAO.getBillWaterById(wxPayDetailDO.getBillId());
                        billWaterById.setIsPayed(1);
                        billWaterById.setGmtPay(new Date());
                        billWaterById.setBillPayId(payId);
                        billWaterDAO.updateByIdSelective(billWaterById);
                    } else if ("elec".equals(wxPayDetailDO.getBillType())) {
                        BillElecDO billElecById = billElecDAO.getBillElecById(wxPayDetailDO.getBillId());
                        billElecById.setIsPayed(1);
                        billElecById.setGmtPay(new Date());
                        billElecById.setBillPayId(payId);
                        billElecDAO.updateByIdSelective(billElecById);
                    } else if ("deposit".equals(wxPayDetailDO.getBillType())) {
                        BillExtDO billExtById = billExtDAO.getBillExtById(wxPayDetailDO.getBillId());
                        billExtById.setIsPayed(1);
                        billExtById.setBillPayId(payId);
                        billExtDAO.updateByIdSelective(billExtById);
                    } else if ("other".equals(wxPayDetailDO.getBillType())) {
                        BillExtDO billExtById = billExtDAO.getBillExtById(wxPayDetailDO.getBillId());
                        billExtById.setIsPayed(1);
                        billExtById.setBillPayId(payId);
                        billExtDAO.updateByIdSelective(billExtById);
                    }
                }
            }
        });

        bizResult.success = true;

        return bizResult;
    }

    @Override
    public BizResult queryMySuite() {
        BizResult bizResult = new BizResult();
        Long accessId = AuthUser.getCurrentUser().getUserId();
        final WxAccessDO wxAccessById = wxAccessDAO.getWxAccessById(accessId);
        if(wxAccessById == null){
            bizResult.code= CommonResultCode.PERM_ERROR;
            return  bizResult;
        }
        WxSuiteRelQuery wxSuiteRelQuery = new WxSuiteRelQuery();
        wxSuiteRelQuery.setPageSize(1000);
        wxSuiteRelQuery.setUnionid(wxAccessById.getUnionid());
        wxSuiteRelQuery.setOpenid(wxAccessById.getOpenid());
        List<WxSuiteRelDO> wxSuiteRelDOs = wxSuiteRelDAO.selectForPage(wxSuiteRelQuery);
        if (wxSuiteRelDOs.size() == 0) {
            bizResult.success = true;
            return bizResult;
        }
        List<SuiteView> suiteViewList = new ArrayList<SuiteView>();
        for (WxSuiteRelDO wxSuiteRelDO : wxSuiteRelDOs) {
            SuiteView suiteView = new SuiteView();
            SuiteDO suiteById = suiteDAO.getSuiteById(wxSuiteRelDO.getSuiteId());
            suiteView.setSuiteDO(suiteById);
            if (suiteById == null) {
                continue;
            }
            UnitDO unitById = unitDAO.getUnitById(suiteById.getUnitId());
            if (unitById == null) {
                continue;
            }
            suiteView.setUnitDO(unitById);
            BuildingDO buildingById = buildingDAO.getBuildingById(unitById.getBuildingId());
            if (buildingById == null) {
                continue;
            }
            suiteView.setBuildingDO(buildingById);
            VillageDO villageDO = villageDAO.getVillageById(buildingById.getVillageId());
            if (villageDO == null) {
                continue;
            }
            suiteView.setVillageDO(villageDO);
            suiteViewList.add(suiteView);
        }

        bizResult.data.put("suiteViewList", suiteViewList);
        bizResult.success = true;
        return bizResult;
    }
}
